use hirun::net::*;
use hirun::runtime;

mod http;
use http::*;

async fn server_conn(conn: Fd, size: usize) {
    conn.set_linger(Some(Duration::default()));
    let mut aio = AioFd::new(&conn);
    loop {
        let mut req = HttpReq::new();
        if let Err(_) = req.read(&mut aio).await {
            break;
        }

        let rsp = HttpRsp::new(size);
        if let Err(_) = rsp.write(&mut aio).await {
            break;
        }
    }
    let _ = conn.shutdown(SHUT_RDWR);
}

async fn server(port: u16) {
    let size = runtime::env_unsigned::<usize>("http_body_size", 10, 10240);
    let addr = SocketAddr::inet("127.0.0.1", port).unwrap();
    let server = match Fd::tcp_server(&addr) {
        Ok(server) => server,
        Err(_e) => {
            println!("tcp_server fail: {_e}");
            return;
        }
    };
    let mut aio = AioFd::new(&server);
    loop {
        match aio.accept().await {
            Ok((conn, _)) => {
                let _ = runtime::spawn(server_conn(conn, size));
            }
            Err(_e) => {}
        };
    }
}

use std::time::*;

fn main() {
    let _ = runtime::Builder::new()
        .name("http")
        //.nth(4)
        .build();
    let _ = runtime::block_on(server(2000));
}
